/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bs.stock.dao;

import bs.global.dao.BaseDAO;
import bs.stock.modelo.Deposito;
import bs.stock.modelo.ItemMovimientoStock;
import bs.stock.modelo.Producto;
import bs.stock.modelo.Stock;
import bs.stock.vistas.StockProductoDeposito;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.Query;

@Stateless
public class StockDAO extends BaseDAO {

    @EJB
    ProductoDAO productoDAO;
    @EJB
    DepositoDAO depositoDAO;

    public BigDecimal getDisponibleProducto(Stock s){

        try {          

            Query q = (Query) em.createQuery("SELECT SUM(s.stocks) "
                    + "FROM ST_Stock s "
                    + "WHERE s.tippro = :tippro "
                    + "AND s.artcod = :artcod "
                    + "AND s.nserie = :nserie "
                    + "AND s.envase = :envase "
                    + "AND s.ndespa = :ndespa "
                    + "AND s.notros = :notros "
                    + "AND s.natrib = :natrib "
                    + "AND s.nubica = :nubica "
                    + "AND s.nestan = :nestan "
                    + "AND s.deposi = :deposi " );

            q.setParameter("artcod",s.getCodigo());
            q.setParameter("nserie",s.getNserie());
            q.setParameter("envase",s.getEnvase());
            q.setParameter("ndespa",s.getNdespa());
            q.setParameter("notros",s.getNotros());
            q.setParameter("natrib",s.getNatrib());
            q.setParameter("nubica",s.getNubica());
            q.setParameter("nestan",s.getNestan());
            q.setParameter("deposi",s.getDeposito());
            

            return (BigDecimal) q.getSingleResult();
        } catch (Exception e) {
            System.out.println("No se puede obtener disponible en stock" + e.getMessage());
            return BigDecimal.ZERO;
        }

    }

    public List<StockProductoDeposito> verStockPorDeposito(Deposito d) {
        try {

            sincronizacionTemporal("st_stockdepo");
            
            Query q = (Query) em.createQuery("SELECT s FROM ST_StockProductoDeposito s "
                    + "WHERE s.codigoDeposito = :deposi "  );
            
            q.setParameter("deposi",d.getCodigo());
            return q.getResultList();
        } catch (Exception e) {
            System.out.println("No se puede obtener stock por deposito " + e.getMessage());
            return new ArrayList<StockProductoDeposito>();
        }
    }

    public List<StockProductoDeposito> verStockPorProducto(Producto p) {
        try {

            sincronizacionTemporal("st_stockdepo");
            
            Query q = (Query) em.createQuery("SELECT s FROM ST_StockProductoDeposito s "
                    + "WHERE s.tippro = :tippro "
                    + "AND s.artcod = :artcod ");

            q.setParameter("artcod",p.getCodigo());
            return q.getResultList();
        } catch (Exception e) {
            System.out.println("No se puede obtener stock por producto " + e.getMessage());
            return new ArrayList<StockProductoDeposito>();
        }
    }

    public List<Stock> getStockByProductoDeposito(Producto p,Deposito d){
        try {

            Query q = em.createQuery("SELECT s FROM ST_Stock s "
                    + "WHERE s.tippro = :tippro "
                    + "AND s.artcod = :artcod "
                    + "AND s.deposi = :deposi " );

            q.setParameter("artcod",p.getCodigo());
            q.setParameter("deposi",d.getCodigo());
            

            return q.getResultList();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("No se puede obtener stock por producto y deposito" + e.getMessage());
            return new ArrayList<Stock>();
        }
    }

    public BigDecimal getStockAFecha(Producto p,Deposito d, Date fecha){

        try {

            Query q = em.createNativeQuery("Select IFNULL(sum(strmvi.STRMVI_CANTID),0)  "
                    + " From strmvh,strmvi,stmpdh"
                    + " Where strmvh.STRMVH_MODFOR = strmvi.STRMVI_MODFOR "
                    + "	And strmvi.STRMVI_TIPPRO = stmpdh.TIPPRO "
                    + "	And strmvi.STRMVI_ARTCOD = stmpdh.ARTCOD "
                    + " And strmvh.STRMVH_CODFOR = strmvi.STRMVI_CODFOR "
                    + "	And strmvh.STRMVH_NROFOR = strmvi.STRMVI_NROFOR "
                    + "	And strmvh.STRMVH_SUCURS = strmvi.STRMVI_SUCURS "
                    + "	And strmvh.STRMVH_FCHMOV <= ?1 "
                    + "	And strmvi.STRMVI_TIPPRO = ?2 "
                    + "	And strmvi.STRMVI_ARTCOD = ?3 "
                    + "	And strmvi.STRMVI_DEPOSI = ?4 "                    
                    + "	And strmvi.STRMVI_NSERIE = ?6 ");

            q.setParameter("2",p.getCodigo());
            q.setParameter("3","");
            q.setParameter("4","");
            q.setParameter("5","");
            q.setParameter("6","");

            return (BigDecimal) q.getSingleResult();
            
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("No se puede obtener stock por producto a fecha" + e.getMessage());
            return BigDecimal.ZERO;
        }

    }

    public List<ItemMovimientoStock> getMovimientosEntreFechas(Producto p, Deposito d, Date fDesde, Date fHasta) {
        try {

            Query q = em.createQuery("SELECT i FROM ST_ItemMovimiento i "
                    + "WHERE i.tippro = :tippro "
                    + "AND i.artcod = :artcod "
                    + "AND i.deposi = :deposi "
                    + "AND i.movimiento.fchmov BETWEEN :fDesde AND :fHasta ");

            q.setParameter("artcod",p.getCodigo());
            q.setParameter("deposi",d.getCodigo());            
            q.setParameter("fDesde",fDesde);
            q.setParameter("fHasta",fHasta);

            return q.getResultList();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("No se puede obtener stock entre fechas" + e.getMessage());
            return new ArrayList<ItemMovimientoStock>();
        }
    }

}
